package com.zziq.cloudpicturebank.utils;

import cn.hutool.core.net.url.UrlPath;
import org.springframework.scheduling.annotation.Async;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class KMeansColorExtractor {

    public static Color getDominantColor(URL imagePath, int k) throws IOException {
        BufferedImage image = ImageIO.read(imagePath);
        List<Color> colors = new ArrayList<>();

        // 收集图片中的颜色
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                int rgb = image.getRGB(x, y);
                colors.add(new Color(rgb));
            }
        }

        // K-Means 聚类
        List<Color> centroids = initializeCentroids(colors, k);
        boolean changed;
        do {
            List<List<Color>> clusters = new ArrayList<>();
            for (int i = 0; i < k; i++) {
                clusters.add(new ArrayList<>());
            }
            for (Color color : colors) {
                int index = findNearestCluster(color, centroids);
                clusters.get(index).add(color);
            }
            List<Color> newCentroids = new ArrayList<>();
            for (List<Color> cluster : clusters) {
                newCentroids.add(calculateCentroid(cluster));
            }
            changed = !newCentroids.equals(centroids);
            centroids = newCentroids;
        } while (changed);

        // 返回聚类中心的颜色
        return centroids.get(0);
    }

    private static List<Color> initializeCentroids(List<Color> colors, int k) {
        Random random = new Random();
        List<Color> centroids = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            centroids.add(colors.get(random.nextInt(colors.size())));
        }
        return centroids;
    }

    private static int findNearestCluster(Color color, List<Color> centroids) {
        int minIndex = 0;
        double minDistance = Double.MAX_VALUE;
        for (int i = 0; i < centroids.size(); i++) {
            double distance = calculateDistance(color, centroids.get(i));
            if (distance < minDistance) {
                minDistance = distance;
                minIndex = i;
            }
        }
        return minIndex;
    }

    private static double calculateDistance(Color c1, Color c2) {
        int r1 = c1.getRed(), g1 = c1.getGreen(), b1 = c1.getBlue();
        int r2 = c2.getRed(), g2 = c2.getGreen(), b2 = c2.getBlue();
        return Math.sqrt(Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2));
    }

    private static Color calculateCentroid(List<Color> cluster) {
        int r = 0, g = 0, b = 0;
        for (Color color : cluster) {
            r += color.getRed();
            g += color.getGreen();
            b += color.getBlue();
        }
        int size = cluster.size();
        return new Color(r / size, g / size, b / size);
    }


}